home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr22 / cpuid593.zip / CPUID592.ASM < prev    next >
Assembly Source File  |  1993-05-01  |  7KB  |  229 lines

  1.     TITLE    CPUID
  2. ;v5.92    Toad Hall Tweak, 1 Jul 91
  3. ;    - Tightened up code a little, tabified.
  4. ;      I have *no* idea what he did to make the original
  5. ;      CPUID.EXE 6Kb long!  debug enabled?
  6. ;    - No functional changes.
  7. ;    David Kirschbaum
  8. ;    kirsch@usasoc.soc.mil
  9.  
  10.     DOSSEG
  11.     .model  small
  12.  
  13.     .stack  100h
  14.  
  15.     .data
  16. fp_status    dw    ?
  17. id_mess        db    "This system has a$"
  18. fp_8087        db    " and an 8087 math coprocessor$"
  19. fp_80287    db    " and an i287tm math coprocessor$"
  20. fp_80387    db    " and an i387tm math coprocessor$"
  21. c8086        db    "n 8086/8088 microprocessor$"
  22. c286        db    "n 80286 microprocessor$"
  23. c386        db    " i386tm microprocessor$"
  24. c486        db    " i486tm DX microprocessor or i487tm SX math coprocessor$"
  25. c486nfp        db    " i486tm SX microprocessor$"
  26. period        db    ".$",13,10
  27. present_86    db    0    ;v5.92
  28. present_286    db    0    ;v5.92
  29. present_386    db    0    ;v5.92
  30. present_486    db    0    ;v5.92
  31.  
  32. ;
  33. ; The purpose of this code is to allow the user the ability to identify the
  34. ; processor and coprocessor that is currently in the system.  The algorithm
  35. ; of the program is to first determine the processor id.
  36. ; When that is accomplished, the program continues to then identify whether
  37. ; a coprocessor exists in the system.  If a coprocessor or integrated
  38. ; coprocessor exists, the program will identify the coprocessor id.  If one
  39. ; does not exist, the program then terminates.
  40. ;
  41.     .code
  42. start:
  43.     mov    ax,@data
  44.     mov    ds,ax                ; set segment register
  45.  
  46.     mov    dx,offset id_mess        ; print header message
  47.     mov    ah,9h
  48.     int    21h
  49.  
  50. ;
  51. ;    8086 CPU check
  52. ;    Bits 12-15 are always set on the 8086 processor.
  53. ;
  54.     mov    cx,0F000H        ;handy constant            v5.92
  55.     pushf                ; save EFLAGS
  56.     pop    bx            ; store EFLAGS in BX
  57.     mov    ax,0fffh        ; clear bits 12-15
  58.     and    ax,bx            ;    in EFLAGS
  59.     push    ax            ; store new EFLAGS value on stack
  60.     popf                ; replace current EFLAGS value
  61.     pushf                ; set new EFLAGS
  62.     pop    ax            ; store new EFLAGS in AX
  63.     and    ax,cx    ;0f000h        ; if bits 12-15 are set,    v5.92
  64.     cmp    ax,cx    ;0f000h        ; then CPU is an 8086/8088    v5.92
  65.     mov    dx,offset c8086        ; store 8086/8088 message
  66.     mov    present_86,1        ; turn on 8086/8088 flag
  67.     je    check_fpu        ; if CPU is 8086/8088, check for 8087
  68.  
  69. ;
  70. ;    80286 CPU check
  71. ;    Bits 12-15 are always clear on the 80286 processor.
  72. ;
  73.  
  74.     or    bx,cx    ;0f000h        ; try to set bits 12-15        v5.92
  75.     push    bx
  76.     popf
  77.     pushf
  78.     pop    ax
  79.     and    ax,cx    ;0f000h        ; if bits 12-15 are cleared    v5.92
  80.     mov    dx,offset c286        ; then CPU is an 80286
  81.     mov    present_86,0        ; turn off 8086/8088 flag
  82.     mov    present_286,1        ; turn on 80286 flag
  83.     jz    check_fpu        ; if CPU is 80286, check for 80287
  84.  
  85. ;
  86. ; i386 CPU check
  87. ; The AC bit, bit #18, is a new bit introduced in the EFLAGS register on the
  88. ;  i486 DX CPU to generate alignment faults.  This bit can be set on the
  89. ;  i486 DX CPU, but not on the i386 CPU.
  90.  
  91.  
  92.     mov    bx,sp            ; save current stack pointer to align it
  93.     and    sp,not 3        ; align stack to avoid AC fault
  94.     db    66h
  95.     pushf                ; push original EFLAGS
  96.     db    66h
  97.     pop    ax            ; get original EFLAGS
  98.     db    66h
  99.     mov    cx,ax            ; save original EFLAGS
  100.     db    66h            ; xor EAX,40000h
  101.     xor    ax,0            ; flip AC bit in EFLAGS
  102.     dw    4            ; upper 16-bits of xor constant
  103.     db    66h
  104.     push    ax            ; save for EFLAGS
  105.     db    66h
  106.     popf                ; copy to EFLAGS
  107.     db    66h
  108.     pushf                ; push EFLAGS
  109.     db    66h
  110.     pop    ax            ; get new EFLAGS value
  111.     db    66h
  112.     xor    ax,cx            ; if AC bit cannot be changed, CPU is
  113.     mov    dx,offset c386        ; store i386 message
  114.     mov    present_286,0        ; turn off 80286 flag
  115.     mov    present_386,1        ; turn on i386 flag
  116.     je    check_fpu        ; if CPU is i386, now check for
  117.                     ;       80287/80387 MCP
  118.  
  119. ;
  120. ;    i486 DX CPU / i487 SX MCP and i486 SX CPU checking
  121. ;
  122.     mov    dx,offset c486nfp    ; store 486NFP message
  123.     mov    present_386,0        ; turn off i386 flag
  124.     mov    present_486,1        ; turn on i486 flag
  125.  
  126. ;
  127. ; Co-processor checking begins here for the 8086/80286/i386 CPUs.
  128. ; The algorithm is to determine whether or not the floating-point status
  129. ; and control words can be written to.  If they are not, no coprocessor exists.
  130. ; If the status and control words can be written to, the correct coprocessor
  131. ; is then determined depending on the processor id.  Coprocessor checks are
  132. ; first performed for an 8086, 80286 and a i486 DX CPU.  If the coprocessor id
  133. ; is still undetermined, the system must contain a i386 CPU.  The i386 CPU may
  134. ; work with either an 80287 or an 80387.  The infinity of the coprocessor must
  135. ; be checked to determine the correct coprocessor id.
  136. ;
  137.  
  138. check_fpu:                ; check for 8087/80287/80387
  139.     fninit                ; reset FP status word
  140.     mov    fp_status,5a5ah        ; initialize temp word to non-zero value
  141.     fnstsw  fp_status        ; save FP status word
  142.     mov    ax,fp_status        ; check FP status word
  143. ;v5.92    cmp    al,0
  144.     or    al,al            ; see if correct status with written
  145.     jne    print_one        ; jump if not Valid, no NPX installed
  146.  
  147.     fnstcw  fp_status        ; save FP control word
  148.     mov    ax,fp_status        ; check FP control word
  149.     and    ax,103fh        ; see if selected parts looks OK
  150.     cmp    ax,3fh            ; check that ones and zeroes correctly
  151.                     ; read
  152. ;v5.92    jne    print_one        ; jump if not Valid, no NPX installed
  153.     jne    msgterm            ; not valid, no NPX installed    v5.92
  154.  
  155.     cmp    present_486,1        ; check if i486 flag is on
  156. ;v5.92    je    is_486            ; if so, jump to print 486 message
  157. ;v5.92    jmp    not_486            ;    else continue with 386 checking
  158.     jne    not_486            ;nope, continue 386 checking    v5.92
  159.                     ;yep, display i486 msg        v5.92
  160. ;is_486:
  161.     mov    dx,offset c486        ; store i486 message
  162. ;v5.92    jmp    print_one
  163.     jmp    msgterm            ;display i486 message, terminate v5.92
  164.  
  165. not_486:
  166.     cmp    present_386,1        ; check if i386 flag is on
  167.     jne    print_87_287        ; if i386 flag not on, check NPX for
  168.                     ;    8086/8088/80286
  169.     mov    ah,9h            ; print out i386 CPU ID first
  170.     int    21h
  171.  
  172. ;
  173. ;   80287/80387 check for the i386 CPU
  174. ;
  175.     fld1                ; must use default control from FNINIT
  176.     fldz                ; form infinity
  177.     fdiv                ; 8087/80287 says +inf = -inf
  178.     fld    st            ; form negative infinity
  179.     fchs                ; 80387 says +inf <> -inf
  180.     fcompp                ; see if they are the same
  181.                     ; and remove them
  182.     fstsw    fp_status        ; look at status from FCOMPP
  183.     mov    ax,fp_status
  184.     mov    dx,offset fp_80287    ; store 80287 message
  185.     sahf                ; see if infinities matched
  186.     jz    restore_EFLAGS        ; jump if 8087/80287 is present
  187.      mov    dx,offset fp_80387    ; store 80387 message
  188.  
  189. restore_EFLAGS:
  190.     mov    ah,9h            ; print NPX message
  191.     int    21h
  192.     db    66h
  193.     push    cx            ; push ECX
  194.     db    66h
  195.     popf                ; restore original EFLAGS register
  196.     mov    sp,bx            ; restore original stack pointer
  197.     jmp    short exit
  198.  
  199. print_one:
  200. ;v5.92    mov    ah,9h            ; print out CPU ID with no NPX
  201. ;    int    21h
  202. ;    jmp    exit
  203.     jmp    short msgterm        ;print out CPU ID with no NPX    v5.92
  204.  
  205. print_87_287:
  206.     mov    ah,9h            ; print out 8086/8088/80286 first
  207.     int    21h
  208.     cmp    present_86,1        ; if 8086/8088 flag is on
  209.     mov    dx,offset fp_8087    ; store 8087 message
  210.     je    print_fpu
  211.      mov    dx,offset fp_80287    ; else CPU=80286, store 80287 message
  212.  
  213. print_fpu:
  214. ;v5.92    mov    ah,9h            ; print out NPX
  215. ;    int    21h
  216. ;dumb    jmp    exit
  217.     jmp    short msgterm        ;print out NPX            v5.92
  218.  
  219. exit:
  220.     mov    dx,offset period    ; print out a period to end message
  221. msgterm:
  222.     mov    ah,9h
  223.     int    21h
  224.  
  225.     mov    ax,4c00h        ; terminate program
  226.     int    21h
  227.  
  228.     end    start
  229.